package com.eshop.modules.activity.service.impl;

import java.lang.invoke.SerializedLambda;
import java.util.Comparator;
import java.util.function.Function;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.eshop.modules.product.service.dto.ProductResultDto;
import java.util.HashMap;
import com.eshop.modules.product.service.dto.ProductFormatDto;
import cn.hutool.core.collection.ListUtil;
import com.eshop.modules.product.service.dto.FromatDetailDto;
import com.eshop.enums.SpecTypeEnum;
import java.math.BigDecimal;
import cn.hutool.core.bean.BeanUtil;
import java.io.IOException;
import com.eshop.utils.FileUtil;
import java.util.ArrayList;
import javax.servlet.http.HttpServletResponse;
import com.eshop.common.utils.QueryHelpPlus;
import java.util.Iterator;
import java.util.LinkedHashMap;
import com.eshop.enums.ProductTypeEnum;
import com.eshop.modules.activity.domain.StoreVisit;
import com.eshop.modules.activity.domain.StorePink;
import com.eshop.modules.activity.service.dto.StoreCombinationDto;
import com.github.pagehelper.PageInfo;
import org.springframework.data.domain.Pageable;
import com.eshop.modules.activity.service.dto.StoreCombinationQueryCriteria;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import org.springframework.beans.BeanUtils;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.eshop.modules.activity.vo.CombinationQueryVo;
import com.eshop.modules.activity.service.dto.PinkAllDto;
import com.eshop.modules.product.domain.StoreProductAttrValue;
import java.util.Map;
import com.eshop.modules.product.vo.StoreProductAttrQueryVo;
import java.util.List;
import com.eshop.exception.BadRequestException;
import cn.hutool.core.util.ObjectUtil;
import java.io.Serializable;
import com.eshop.modules.template.domain.ShippingTemplates;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.eshop.utils.RedisUtil;
import com.eshop.modules.activity.vo.StoreCombinationQueryVo;
import com.eshop.api.EshopException;
import com.eshop.enums.ShopCommonEnum;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import java.util.Date;
import com.eshop.modules.activity.vo.StoreCombinationVo;
import com.eshop.modules.product.service.StoreProductService;
import com.eshop.modules.template.service.ShippingTemplatesService;
import com.eshop.modules.product.service.StoreProductAttrValueService;
import com.eshop.modules.product.service.StoreProductAttrService;
import com.eshop.modules.activity.service.StorePinkService;
import com.eshop.modules.product.service.StoreProductReplyService;
import com.eshop.modules.activity.service.mapper.StoreVisitMapper;
import com.eshop.modules.activity.service.mapper.StorePinkMapper;
import org.springframework.beans.factory.annotation.Autowired;
import com.eshop.dozer.service.IGenerator;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.stereotype.Service;
import com.eshop.modules.activity.service.StoreCombinationService;
import com.eshop.modules.activity.domain.StoreCombination;
import com.eshop.modules.activity.service.mapper.StoreCombinationMapper;
import com.eshop.common.service.impl.BaseServiceImpl;

@Service
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = { Exception.class })
public class StoreCombinationServiceImpl extends BaseServiceImpl<StoreCombinationMapper, StoreCombination> implements StoreCombinationService
{
    @Autowired
    private IGenerator generator;
    @Autowired
    private StorePinkMapper storePinkMapper;
    @Autowired
    private StoreVisitMapper storeVisitMapper;
    @Autowired
    private StoreCombinationMapper storeCombinationMapper;
    @Autowired
    private StoreProductReplyService replyService;
    @Autowired
    private StorePinkService storePinkService;
    @Autowired
    private StoreProductAttrService storeProductAttrService;
    @Autowired
    private StoreProductAttrValueService storeProductAttrValueService;
    @Autowired
    private ShippingTemplatesService shippingTemplatesService;
    @Autowired
    private StoreProductService storeProductService;
    
    public StoreCombinationVo getDetail(final Long id, final Long uid) {
        final Date now = new Date();
        final StoreCombination storeCombination = (StoreCombination)((((this.lambdaQuery().eq(StoreCombination::getId, id)).eq(StoreCombination::getIsShow, ShopCommonEnum.SHOW_1.getValue())).le(StoreCombination::getStartTime, now)).ge(StoreCombination::getStopTime, now)).one();
        if (storeCombination == null) {
            throw new EshopException("拼团不存在或已下架");
        }
        final Map<String, Object> returnMap = this.storeProductAttrService.getProductAttrDetail(storeCombination.getProductId());
        final StoreCombinationQueryVo storeCombinationQueryVo = (StoreCombinationQueryVo)this.generator.convert(storeCombination, (Class)StoreCombinationQueryVo.class);
        final StoreCombinationVo storeCombinationVo = new StoreCombinationVo();
        storeCombinationVo.setStoreInfo(storeCombinationQueryVo);
        storeCombinationVo.setReply(this.replyService.getReply(storeCombinationQueryVo.getProductId()));
        final int replyCount = this.replyService.productReplyCount(storeCombinationQueryVo.getProductId());
        storeCombinationVo.setReplyCount(replyCount);
        storeCombinationVo.setReplyChance(this.replyService.replyPer(storeCombinationQueryVo.getProductId()));
        final String storeFreePostage = (String)RedisUtil.get("store_free_postage");
        String tempName = "";
        if (StrUtil.isBlank((CharSequence)storeFreePostage) || !NumberUtil.isNumber((CharSequence)storeFreePostage) || Integer.valueOf(storeFreePostage) == 0) {
            tempName = "全国包邮";
        }
        else {
            final ShippingTemplates shippingTemplates = (ShippingTemplates)this.shippingTemplatesService.getById((Serializable)storeCombination.getTempId());
            if (!ObjectUtil.isNotNull(shippingTemplates)) {
                throw new BadRequestException("请配置运费模板");
            }
            tempName = shippingTemplates.getName();
        }
        storeCombinationVo.setTempName(tempName);
        final PinkAllDto pinkAllDto = this.storePinkService.getPinkAll(id);
        storeCombinationVo.setPindAll(pinkAllDto.getPindAll());
        storeCombinationVo.setPink(pinkAllDto.getList());
        storeCombinationVo.setPinkOkList(this.storePinkService.getPinkOkList(uid));
        storeCombinationVo.setPinkOkSum(this.storePinkService.getPinkOkSumTotalNum());
        storeCombinationVo.setProductAttr((List<StoreProductAttrQueryVo>) returnMap.get("productAttr"));
        storeCombinationVo.setProductValue((Map<String, StoreProductAttrValue>) returnMap.get("productValue"));
        return storeCombinationVo;
    }
    
    public CombinationQueryVo getList(final int page, final int limit) {
        final CombinationQueryVo combinationQueryVo = new CombinationQueryVo();
        final Date nowTime = new Date();
        final Page<StoreCombination> pageModel = (Page<StoreCombination>)new Page((long)page, (long)limit);
        final LambdaQueryWrapper<StoreCombination> wrapper = (LambdaQueryWrapper<StoreCombination>)new LambdaQueryWrapper();
        (((wrapper.eq(StoreCombination::getIsShow, 1)).le(StoreCombination::getStartTime, nowTime)).ge(StoreCombination::getStopTime, nowTime)).orderByDesc(StoreCombination::getSort);
        final IPage<StoreCombination> yxStoreCombinationIPage = this.storeCombinationMapper.selectPage((IPage<StoreCombination>)pageModel, (Wrapper<StoreCombination>)wrapper);
        final List<StoreCombinationQueryVo> collect = yxStoreCombinationIPage.getRecords().stream().map(i -> {
            StoreCombinationQueryVo storeCombinationQueryVo = new StoreCombinationQueryVo();
            BeanUtils.copyProperties(i, storeCombinationQueryVo);
            return storeCombinationQueryVo;
        }).collect(Collectors.toList());
        combinationQueryVo.setStoreCombinationQueryVos(collect);
        combinationQueryVo.setLastPage(yxStoreCombinationIPage.getPages());
        return combinationQueryVo;
    }
    
    public Map<String, Object> queryAll(final StoreCombinationQueryCriteria criteria, final Pageable pageable) {
        this.getPage(pageable);
        final PageInfo<StoreCombination> page = (PageInfo<StoreCombination>)new PageInfo((List)this.queryAll(criteria));
        final List<StoreCombinationDto> combinationDTOS = (List<StoreCombinationDto>)this.generator.convert(page.getList(), (Class)StoreCombinationDto.class);
        for (final StoreCombinationDto combinationDTO : combinationDTOS) {
            combinationDTO.setCountPeopleAll(this.storePinkMapper.selectCount(Wrappers.<StorePink>lambdaQuery().eq(StorePink::getCid, combinationDTO.getId())));
            combinationDTO.setCountPeoplePink(this.storePinkMapper.selectCount((Wrappers.<StorePink>lambdaQuery().eq(StorePink::getCid, combinationDTO.getId())).eq(StorePink::getKId, 0)));
            combinationDTO.setCountPeopleBrowse(this.storeVisitMapper.selectCount((Wrappers.<StoreVisit>lambdaQuery().eq(StoreVisit::getProductId, combinationDTO.getId())).eq(StoreVisit::getProductType, ProductTypeEnum.COMBINATION.getValue())));
        }
        final Map<String, Object> map = new LinkedHashMap<String, Object>(2);
        map.put("content", combinationDTOS);
        map.put("totalElements", page.getTotal());
        return map;
    }
    
    public List<StoreCombination> queryAll(final StoreCombinationQueryCriteria criteria) {
        return (List<StoreCombination>)((StoreCombinationMapper)this.baseMapper).selectList((Wrapper)QueryHelpPlus.getPredicate(StoreCombination.class, criteria));
    }
    
    public void download(final List<StoreCombinationDto> all, final HttpServletResponse response) throws IOException {
        final List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
        for (final StoreCombinationDto yxStoreCombination : all) {
            final Map<String, Object> map = new LinkedHashMap<String, Object>();
            map.put("商品id", yxStoreCombination.getProductId());
            map.put("推荐图", yxStoreCombination.getImage());
            map.put("轮播图", yxStoreCombination.getImages());
            map.put("活动标题", yxStoreCombination.getTitle());
            map.put("参团人数", yxStoreCombination.getPeople());
            map.put("简介", yxStoreCombination.getInfo());
            map.put("价格", yxStoreCombination.getPrice());
            map.put("排序", yxStoreCombination.getSort());
            map.put("销量", yxStoreCombination.getSales());
            map.put("库存", yxStoreCombination.getStock());
            map.put("推荐", yxStoreCombination.getIsHost());
            map.put("产品状态", yxStoreCombination.getIsShow());
            map.put(" combination", yxStoreCombination.getCombination());
            map.put("商户是否可用1可用0不可用", yxStoreCombination.getMerUse());
            map.put("是否包邮1是0否", yxStoreCombination.getIsPostage());
            map.put("邮费", yxStoreCombination.getPostage());
            map.put("拼团内容", yxStoreCombination.getDescription());
            map.put("拼团开始时间", yxStoreCombination.getStartTime());
            map.put("拼团结束时间", yxStoreCombination.getStopTime());
            map.put("拼团订单有效时间", yxStoreCombination.getEffectiveTime());
            map.put("拼团产品成本", yxStoreCombination.getCost());
            map.put("浏览量", yxStoreCombination.getBrowse());
            map.put("单位名", yxStoreCombination.getUnitName());
            list.add(map);
        }
        FileUtil.downloadExcel((List)list, response);
    }
    
    public void onSale(final Long id, Integer status) {
        if (ShopCommonEnum.SHOW_1.getValue().equals(status)) {
            status = ShopCommonEnum.SHOW_0.getValue();
        }
        else {
            status = ShopCommonEnum.SHOW_1.getValue();
        }
        final StoreCombination storeCombination = new StoreCombination();
        storeCombination.setIsShow(status);
        storeCombination.setId(id);
        this.saveOrUpdate(storeCombination);
    }
    
    public boolean saveCombination(final StoreCombinationDto resources) {
        final ProductResultDto resultDTO = this.computedProduct(resources.getAttrs());
        final StoreCombination storeCombination = new StoreCombination();
        BeanUtil.copyProperties(resources, storeCombination, new String[] { "images" });
        if (resources.getImages().isEmpty()) {
            throw new EshopException("请上传轮播图");
        }
        storeCombination.setPrice(BigDecimal.valueOf(resultDTO.getMinPrice()));
        storeCombination.setProductPrice(BigDecimal.valueOf(resultDTO.getMinOtPrice()));
        storeCombination.setCost(resultDTO.getMinCost().intValue());
        storeCombination.setStock(resultDTO.getStock());
        storeCombination.setImages(String.join(",", resources.getImages()));
        this.saveOrUpdate(storeCombination);
        if (SpecTypeEnum.TYPE_0.getValue().equals(resources.getSpecType())) {
            final FromatDetailDto fromatDetailDto = FromatDetailDto.builder().value("规格").detailValue("").attrHidden("").detail(ListUtil.toList(new String[] { "默认" })).build();
            final List<ProductFormatDto> attrs = resources.getAttrs();
            final ProductFormatDto productFormatDto = attrs.get(0);
            productFormatDto.setValue1("规格");
            final Map<String, String> map = new HashMap<String, String>();
            map.put("规格", "默认");
            productFormatDto.setDetail(map);
            this.storeProductAttrService.insertYxStoreProductAttr(ListUtil.toList(new FromatDetailDto[] { fromatDetailDto }), ListUtil.toList(new ProductFormatDto[] { productFormatDto }), resources.getProductId());
        }
        else {
            this.storeProductAttrService.insertYxStoreProductAttr(resources.getItems(), resources.getAttrs(), resources.getProductId());
        }
        return true;
    }
    
    private ProductResultDto computedProduct(final List<ProductFormatDto> attrs) {
        Double minPrice = attrs.stream().map(ProductFormatDto::getPinkPrice).min(Comparator.naturalOrder()).orElse(0.0);
        Double minOtPrice = attrs.stream().map(ProductFormatDto::getOtPrice).min(Comparator.naturalOrder()).orElse(0.0);
        Double minCost = attrs.stream().map(ProductFormatDto::getCost).min(Comparator.naturalOrder()).orElse(0.0);
        Integer stock = attrs.stream().map(ProductFormatDto::getPinkStock).reduce(Integer::sum).orElse(0);
        if (stock <= 0) {
            throw new EshopException("库存不能低于0");
        }
        return ProductResultDto.builder().minPrice(minPrice).minOtPrice(minOtPrice).minCost(minCost).stock(stock).build();
    }
    
    private List<ProductFormatDto> ListMapToListBean(final List<Map<String, Object>> listMap) {
        final List<ProductFormatDto> list = new ArrayList<ProductFormatDto>();
        for (final Map<String, Object> m : listMap) {
            list.add((ProductFormatDto)BeanUtil.mapToBean((Map)m, (Class)ProductFormatDto.class, true));
        }
        return list;
    }
}
